package studio.raptor.databus.graph.rule;

import com.google.common.collect.BiMap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import java.util.List;
import java.util.Map;
import java.util.Set;
import studio.raptor.databus.graph.constant.BoActionType;
import studio.raptor.databus.graph.domain.Event;
import studio.raptor.databus.graph.rule.EventRelationship.Relationship;

/**
 * 默认排序规则的实现
 *
 * @author jack
 * @since 1.0
 */
public class DefaultSortingRule extends SortingRule {

  private Event event;
  private Relationship relationship;

  private Set<String> dependIds = Sets.newHashSet();


  public DefaultSortingRule(Event event, Relationship relationship) {
    this.event = event;
    this.relationship = relationship;
  }



  @Override
  public DefaultSortingRule sortByParty() {
    Long partyId = event.getPartyId();
    String eventId = event.getEventId();
    String boActionType = event.getOrderTypeId();
    BiMap<Long, String> depend = relationship.partyRule;

    if (null == partyId || 0==partyId || boActionType == null) {
      return this;
    }
    if (depend.containsKey(partyId)) {
      dependIds.add(depend.get(partyId));
    }
    if (boActionType.indexOf(BoActionType.ADD_CUST) >= 0) {
      depend.forcePut(partyId, eventId);
    }
    return this;
  }

  @Override
  public DefaultSortingRule sortByModifyParty() {
    Long partyId = event.getPartyId();
    String eventId = event.getEventId();
    String boActionType = event.getOrderTypeId();
    BiMap<Long, String> depend = relationship.modifyPartyRule;

    if (partyId == null || 0 == partyId || boActionType == null) {
      return this;
    }

    if (boActionType.indexOf(BoActionType.MODIFY_CUST) >= 0) {
      if (depend.containsKey(partyId)) {
        dependIds.add(depend.get(partyId));
      }
      depend.forcePut(partyId, eventId);
    }
    return this;
  }


  @Override
  public DefaultSortingRule sortByAcct() {
    List<Long> acctIds = event.getAccountId();
    String eventId = event.getEventId();
    String boActionType = event.getOrderTypeId();
    Map<Long, String> depend = relationship.accountRule;
    SetMultimap<String, Long> dependReverse = relationship.accountRuleReverse;

    if (null == acctIds) {
      return this;
    }

    boolean addOrModify = false;
    if (boActionType.indexOf(BoActionType.ADD_ACCT) >= 0) {
      addOrModify = true;
    }
    for (int i = 0, size = acctIds.size(); i < size; i++) {
      Long acctId = acctIds.get(i);
      if (depend.containsKey(acctId)) {
        String dependId = depend.get(acctId);
        dependIds.add(dependId);
        dependReverse.remove(dependId, acctId);
      }
      if (addOrModify) {
        dependReverse.put(eventId, acctId);
        depend.put(acctId, eventId);
      }
    }
    return this;
  }

  @Override
  public DefaultSortingRule sortByMofifyAcct() {

    List<Long> acctIds = event.getAccountId();
    String eventId = event.getEventId();
    String boActionType = event.getOrderTypeId();
    Map<Long, String> depend = relationship.modifyAccountRule;
    SetMultimap<String, Long> dependReverse = relationship.modifyAccountRuleReverse;

    if (null == acctIds || null == dependReverse) {
      return this;
    }

    if (boActionType.indexOf(BoActionType.MODIFY_ACCT) > 0) {
      for (int i = 0, size = acctIds.size(); i < size; i++) {
        Long acctId = acctIds.get(i);
        if (depend.containsKey(acctId)) {
          String dependId = depend.get(acctId);
          dependIds.add(dependId);
          dependReverse.remove(dependId, acctId);
        }
        dependReverse.put(eventId, acctId);
        depend.put(acctId, eventId);
      }
    }
    return this;
  }


  @Override
  public DefaultSortingRule sortByProd() {
    Long prodId = event.getProdId();
    String eventId = event.getEventId();
    List<Long> offerProds = event.getOfferProdId();
    BiMap<Long, String> depend = relationship.prodRule;

    //销售品变更的时候，有依赖产品的，需要插入到依赖关系
    if (null != offerProds) {
      for (int i = 0, size = offerProds.size(); i < size; i++) {
        Long offerProdId = offerProds.get(i);
        if (depend.containsKey(offerProdId)) {
          dependIds.add(depend.get(offerProdId));
        }
      }
    }

    if (null == prodId || 0 == prodId) {
      return this;
    }
    if (depend.containsKey(prodId)) {
      dependIds.add(depend.get(prodId));
    }
    depend.forcePut(prodId, eventId);

    return this;
  }

  @Override
  public DefaultSortingRule sortByOffer() {

    List<Long> offers = event.getOffer();
    String eventId = event.getEventId();
    Map<Long, String> depend = relationship.offerRule;
    SetMultimap<String, Long> dependReverse = relationship.offerRuleReverse;

    if (null == offers) {
      return this;
    }

    for (int i = 0, size = offers.size(); i < size; i++) {
      Long offerId = offers.get(i);
      if (depend.containsKey(offerId)) {
        String dependId = depend.get(offerId);
        dependIds.add(dependId);
        dependReverse.remove(dependId, offerId);
      }
      depend.put(offerId, eventId);
      dependReverse.put(eventId, offerId);
    }
    return this;
  }

  public Relationship getRelationship() {
    return relationship;
  }

  public void setRelationship(Relationship relationship) {
    this.relationship = relationship;
  }

  public Set<String> getDependIds() {
    return dependIds;
  }

  public void setDependIds(Set<String> dependIds) {
    this.dependIds = dependIds;
  }

  public Event getEvent() {
    return event;
  }

  public void setEvent(Event event) {
    this.event = event;
  }
}
